const
  fs = require('fs'),
  ucp = require('./ucp.js'),
  path = require('path'),
  fetch = require('node-fetch')

function writeFile (filename, body) {
  filename = path.resolve(__dirname, filename + '.mjs')

  fs.writeFile(filename, `export default function(cb){cb${body}}`,
    function (err) {
      if (err) throw err
    })
}

function get (url) {
  return fetch(url).then(res => res.text())
}

function regenerate (path, filename) {
  const
    mjs = 'export default function(cb){cb',
    cjs = 'module.exports = require(\'regenerate\')'

  get(ucp + path + '/' + filename + '.js').then(src => {
    if (!src.startsWith(cjs)) throw `File changed: ${path}`

    writeFile(filename, src.slice(cjs.length).replace(/addRange/g, 'r'))
  })
}

function EastAsianWidth () {
  get('https://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt').then(src => {
    let
      i = src.indexOf('\n') + 1,
      seq = '(', range = ')',
      aseq = '(', arange = ')'

    while (i) {
      let c =  src[i]
      if (c !== '\n' && c !== '#') {
        let e = src.indexOf(';', i), c = src[e + 1]

        if (c === 'W' || c === 'F' || c === 'A') {
          let s = src.substring(i, e)
          if (s.length < 6) {
            if (c === 'A')
              aseq += `0x${s},`
            else
              seq += `0x${s},`
          } else if (c === 'A')
            arange += `.r(0x${s.replace('..', ',0x')})`
          else
            range += `.r(0x${s.replace('..', ',0x')})`
          i = e + 2
        }

      }

      i = src.indexOf('\n', i) + 1
    }

    writeFile('EastAsianWide', seq.slice(0, -1) + range)
    writeFile('EastAsianAmbiguous', aseq.slice(0, -1) + arange)
  })
}

[
  // 'Other',
  'Unassigned',
  'Control',
  'Format',
  'Private_Use',
  'Surrogate',

  // 'Letter',
  'Lowercase_Letter',
  'Modifier_Letter',
  'Other_Letter',
  'Titlecase_Letter',
  'Uppercase_Letter',

  // 'Mark',
  'Enclosing_Mark',
  'Nonspacing_Mark',
  'Spacing_Mark',

  // 'Number',
  'Decimal_Number',
  'Letter_Number',
  'Other_Number',

  // 'Punctuation',
  'Close_Punctuation',
  'Connector_Punctuation',
  'Dash_Punctuation',
  'Final_Punctuation',
  'Initial_Punctuation',
  'Open_Punctuation',
  'Other_Punctuation',

  // 'Symbol',
  'Currency_Symbol',
  'Math_Symbol',
  'Modifier_Symbol',
  'Other_Symbol',

  // 'Separator',
  // 'Line_Separator',
  // 'Paragraph_Separator',
  'Space_Separator',

].forEach(s => regenerate('General_Category', s));

[
  'Emoji',
  'ID_Start',
  'ID_Continue'
].forEach(s => regenerate('Binary_Property', s))

EastAsianWidth()
